package org.alex.nettychat.netty.custom.protocol;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufAllocator;
import org.alex.nettychat.netty.custom.serializer.JSONSerializer;
import org.alex.nettychat.netty.custom.serializer.Serializer;
import org.alex.nettychat.netty.custom.serializer.SerializerAlgorithm;

/**
 * 封装包
 *
 * @author : alex
 */
public class PacketCode {
    /**
     * 魔术字
     */
    public static final int MAGIC_NUMBER = 0x12345678;

    /**
     * 编码
     */
    public ByteBuf encode(Packet packet) {
        return encode(ByteBufAllocator.DEFAULT, packet);
    }

    /**
     * 编码
     */
    public ByteBuf encode(ByteBufAllocator byteBufAllocator, Packet packet) {
        // 1创建ByteBuf对象
        ByteBuf byteBuf = byteBufAllocator.ioBuffer();

        // 2序列化java对象
        byte[] bytes = Serializer.DEFAULT.serialize(packet);

        // 3写入进ByteBuf
        byteBuf.writeInt(MAGIC_NUMBER); // 魔数
        byteBuf.writeByte(packet.getVersion()); // 版本号
        byteBuf.writeByte(Serializer.DEFAULT.getSerializerAlgorithm()); // 序列化算法
        byteBuf.writeByte(packet.getCommand()); // 指令
        byteBuf.writeInt(bytes.length); // 数据长度
        byteBuf.writeBytes(bytes); // 数据内容

        return byteBuf;
    }

    /**
     * 解码
     */
    public Packet decode(ByteBuf byteBuf) {
        // 跳过魔术
        byteBuf.skipBytes(4);

        // 跳过版本号
        byteBuf.skipBytes(1);

        // 序列化算法标识
        byte serializeAlgorithm = byteBuf.readByte();

        // 指令
        byte command = byteBuf.readByte();

        // 数据包长度
        int length = byteBuf.readInt();

        byte[] data = new byte[length];
        byteBuf.readBytes(data);

        Class<? extends Packet> requestType = getRequestType(command);

        Serializer serializer = getSerializer(serializeAlgorithm);

        if (requestType != null && serializer != null) {
            return serializer.deserialize(requestType, data);
        }
        return null;
    }

    /**
     * 获取序列化算法
     */
    private Serializer getSerializer(byte serializeAlgorithm) {
        if (SerializerAlgorithm.JSON == serializeAlgorithm) {
            return new JSONSerializer();
        }
        return null;
    }

    /**
     * 获取请求包类型
     */
    private Class<? extends Packet> getRequestType(byte command) {
        if (command == Command.LOGIN_REQUEST) {
            return LoginRequestPacket.class;
        } else if (command == Command.LOGIN_RESPONSE) {
            return LoginResponsePacket.class;
        } else if (command == Command.MESSAGE_REQUEST) {
            return MessageRequestPacket.class;
        } else if (command == Command.MESSAGE_RESPONSE) {
            return MessageResponsePacket.class;
        } else if (command == Command.CREATE_GROUP_REQUEST) {
            return CreateGroupRequestPacket.class;
        } else if (command == Command.CREATE_GROUP_RESPONSE) {
            return CreateGroupResponsePacket.class;
        } else if (command == Command.JOIN_GROUP_REQUEST) {
            return JoinGroupRequestPacket.class;
        } else if (command == Command.JOIN_GROUP_RESPONSE) {
            return JoinGroupResponsePacket.class;
        } else if (command == Command.QUIT_GROUP_REQUEST) {
            return QuitGroupRequestPacket.class;
        } else if (command == Command.QUIT_GROUP_RESPONSE) {
            return QuitGroupResponsePacket.class;
        } else if (command == Command.GET_GROUP_INFO_REQUEST) {
            return GetGroupInfoRequestPacket.class;
        } else if (command == Command.GET_GROUP_INFO_RESPONSE) {
            return GetGroupInfoResponsePacket.class;
        } else if (command == Command.SEND_TO_GROUP_REQUEST) {
            return SendToGroupRequestPacket.class;
        } else if (command == Command.SEND_TO_GROUP_RESPONSE) {
            return SendToGroupResponsePacket.class;
        }
        return null;
    }

    public void encode(ByteBuf byteBuf, Packet packet) {
        // 1 用外界提供的buf

        // 2序列化java对象
        byte[] bytes = Serializer.DEFAULT.serialize(packet);

        // 3写入进ByteBuf
        byteBuf.writeInt(MAGIC_NUMBER); // 魔数
        byteBuf.writeByte(packet.getVersion()); // 版本号
        byteBuf.writeByte(Serializer.DEFAULT.getSerializerAlgorithm()); // 序列化算法
        byteBuf.writeByte(packet.getCommand()); // 指令
        byteBuf.writeInt(bytes.length); // 数据长度
        byteBuf.writeBytes(bytes); // 数据内容
    }
}
